/*
 * Copyright (c) 2020-2021 imlzw@vip.qq.com jweb.cc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cc.jweb.adai.web.console.controller;

import cc.jweb.adai.web.system.log.service.SysLogService;
import cc.jweb.adai.web.system.org.model.SysUser;
import cc.jweb.adai.web.system.sys.model.SysLog;
import cc.jweb.boot.common.lang.Result;
import cc.jweb.boot.controller.JwebController;
import cc.jweb.boot.security.annotation.ClearSecurity;
import cc.jweb.boot.security.exception.AuthenticationException;
import cc.jweb.boot.security.session.account.JwebSecurityAccount;
import cc.jweb.boot.security.utils.JwebSecurityUtils;
import cc.jweb.boot.utils.lang.StringUtils;
import cc.jweb.boot.utils.security.PasswordCryptoTool;
import com.jfinal.aop.Before;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.tx.Tx;
import io.jboot.web.controller.annotation.RequestMapping;
import org.joda.time.DateTime;

import java.util.Date;
import java.util.Map;
import java.util.regex.Pattern;

@RequestMapping(value = "/console")
public class ConsoleController extends JwebController {


    private static Long count = 0l;

    public static void main(String[] args) {
        System.out.println(PasswordCryptoTool.encryptPassword("admin"));
    }

    @ClearSecurity
    public void vcode() {
        renderCaptcha();
    }

    @ClearSecurity
    public void index() {
        if (JwebSecurityUtils.isAuthentication()) {
            setAttr("ts", System.currentTimeMillis());
            render("/WEB-INF/views/console/index.html");
            return;
        }
        setAttr("timestamp", DateTime.now().toDate().getTime());
        render("/WEB-INF/views/console/login.html");
    }

    /**
     * 获取修改资料的页面
     */
    public void modify_page() {
        JwebSecurityAccount account = JwebSecurityUtils.getAccount();
        SysUser sysUser = SysUser.dao.findById(account.getUid());
        setAttr("user", sysUser);
        render("/WEB-INF/views/console/modify_user.html");
    }

    /**
     * 修改资料操作
     */
    @Before({Tx.class})
    public void modifyUser() {
        Map<String, Object> params = getPageParams();
        String userId = JwebSecurityUtils.getAccount().getUid();
        String userName = getPara("user_name");
        String phone = getPara("user_phone");
        String email = getPara("user_email");
        String userPassword = getPara("user_password");
        String userNewPassword = getPara("user_new_password");
        if (StringUtils.isBlank(userName)) {
            renderJson(new Result().setSuccess(false).setMessage("用户姓名不能为空"));
            return;
        }
        if (StringUtils.isBlank(phone)) {
            renderJson(new Result().setSuccess(false).setMessage("手机号不能为空"));
            return;
        }
        if (StringUtils.isBlank(email)) {
            renderJson(new Result().setSuccess(false).setMessage("邮箱不能为空"));
            return;
        }
        SysUser sysUser = SysUser.dao.findById(userId);
        if (sysUser == null) {
            renderJson(new Result().setSuccess(false).setMessage("当前用户不存在！"));
            return;
        }
        sysUser.setUserName(userName);
        sysUser.setUserPhone(phone);
        sysUser.setUserEmail(email);
        if (StringUtils.isNotBlank(userPassword) && StringUtils.isNotBlank(userNewPassword)) { //如果密码框不为空
            String enPasswd = sysUser.getUserPassword();
            if (!PasswordCryptoTool.checkPassword(userPassword, enPasswd)) {
                renderJson(new Result().setSuccess(false).setMessage("原密码不正确，请重新输入！"));
                return;
            }
            sysUser.setUserPassword(PasswordCryptoTool.encryptPassword(userNewPassword));
        }
        sysUser.update();
        // 更新session的username
        JwebSecurityUtils.getAccount().setUname(userName);
        // 标志日志记录
        SysLogService.service.setSyslog("控制台", SysLog.STATUS_SUCCESS, "修改个人资料成功！");
        renderJson(new Result().setSuccess(true).setMessage("修改成功！"));
    }

    public void layout() {
        setAttr("ts", System.currentTimeMillis());
        render("/WEB-INF/views/console/layout.html");
    }


    @ClearSecurity
    public void login() {
        String userAccount = getPara("userAccount"), password = getPara("password");
        if (StringUtils.isBlank(userAccount)) {
            renderJson(new Result().setSuccess(false).setMessage("用户名不能为空！"));
            return;
        }
        if (StringUtils.isBlank(password)) {
            renderJson(new Result().setSuccess(false).setMessage("密码不能为空！"));
            return;
        }
        boolean bl = validateCaptcha("vcode");
        if (!bl) {
            removeCookie("_jfinal_captcha");
            renderJson(new Result(false, "验证码不正确！"));
            return;
        }
        if (!Pattern.matches("^.{5,32}$", password)) {
            renderJson(new Result().setSuccess(false).setMessage("用户名登录密码必须5到32位！"));
            return;
        }
        SysUser user = null;
        try {
            user = SysUser.dao.findFirst("select * from sys_user su where su.user_account = ?", userAccount);
            if (user == null) {
                SysLogService.service.setSyslog("登录", SysLog.STATUS_FAILURE, "登录失败！账号【" + userAccount + "】不存在！");
                throw new AuthenticationException("用户名不存在或密码错误！");
            }
            if (user.getInt("user_status") != 1) {
                SysLogService.service.setSyslog("登录", SysLog.STATUS_FAILURE, "登录失败！该用户【" + user.getUserName() + "】已经被禁用！");
                throw new AuthenticationException("该用户已经被禁用！");
            }
            String user_password = user.getStr("user_password");
            if (StringUtils.isBlank(user_password)) {
                throw new AuthenticationException("用户名未设置密码，请联系管理员设置！");
            }
            if (!PasswordCryptoTool.checkPassword(password, user_password)) {
                SysLogService.service.setSyslog("登录", SysLog.STATUS_FAILURE, "登录失败！用户【" + user.getUserName() + "】密码不正确！");
                throw new AuthenticationException("用户名不存在或密码错误！");
            }
            user.set("user_last_login_datetime", new Date());
            user.update();
            // 注入账户到jwebSecurity中。
            JwebSecurityUtils.setAccount(new JwebSecurityAccount(String.valueOf(user.getUserId()), user.getUserName()));
        } catch (AuthenticationException e) {
            renderJson(new Result(false, e.getMessage()));
            e.printStackTrace();
            return;
        } catch (Exception e) {
            renderJson(new Result(false, "登录异常！" + e.getMessage()));
            SysLogService.service.setSyslog("登录", SysLog.STATUS_FAILURE, "用户【" + user.getUserName() + "】登录异常！" + e.getMessage());
            e.printStackTrace();
            return;
        }
        Result object = new Result();
        object.setSuccess(true);
        SysLogService.service.setSyslog("登录", SysLog.STATUS_SUCCESS, "用户【" + user.getUserName() + "】登录成功！");
        renderJson(object);
    }

    /**
     * 判断用户别名是否已经存在
     */
    @ClearSecurity
    public void checkUserAccount() {
        boolean isExist = false;
        String userAccount = getPara("userAccount");
        if (userAccount != null && userAccount.trim().length() > 0) {
            Number count = Db.queryNumber("select count(1) from sys_user o where o.user_account = ? ", userAccount);
            isExist = count != null && count.intValue() > 0;
        }
        renderJson(new Result().setSuccess(true).setData(isExist));
    }

    public void logout() {
        JwebSecurityAccount account = JwebSecurityUtils.getAccount();
        if (account != null) {
            SysLog sysLog = new SysLog();
            sysLog.setUserId(Integer.parseInt(account.getUid()));
            sysLog.setLogCategory("注销");
            sysLog.setLogStatus(SysLog.STATUS_SUCCESS);
            sysLog.setLogContent("用户【" + account.getUname() + "】注销成功！");
            SysLogService.service.setSyslog(sysLog);
        }
        JwebSecurityUtils.invalidate();
        redirect("/console");
    }

}
